#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/proc_fs.h>
#include <linux/list.h>
#include <asm/uaccess.h>
#include <linux/udp.h>
#include <linux/tcp.h>
#include <linux/skbuff.h>
#include <linux/ip.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include "Definitii.h"

//functia de hooking pentru pachetele de intrare.

 

unsigned int hook_func_in(unsigned int hooknum, struct sk_buff *skb, 

 

        const struct net_device *in, const struct net_device *out,

 

        int (*okfn)(struct sk_buff *)) {


 

   struct iphdr *ip_header = (struct iphdr *)skb_network_header(skb);

 

   struct udphdr *udp_header;

 

   struct tcphdr *tcp_header;

 

   struct list_head *p;

 

   struct regula_firewall *a_rule;

   char src_ip_str[16], dest_ip_str[16];

 

   int i = 0;

 

   unsigned int src_ip = (unsigned int)ip_header->saddr;

 

   unsigned int dest_ip = (unsigned int)ip_header->daddr;

 

   unsigned int src_port = 0;

 

   unsigned int dest_port = 0;

 

   if (ip_header->protocol==17) {

 

       udp_header = (struct udphdr *)(skb_transport_header(skb)+20);

 

       src_port = (unsigned int)ntohs(udp_header->source);

 

       dest_port = (unsigned int)ntohs(udp_header->dest);

 

   } else if (ip_header->protocol == 6) {

 

       tcp_header = (struct tcphdr *)(skb_transport_header(skb)+20);

 

       src_port = (unsigned int)ntohs(tcp_header->source);

 

       dest_port = (unsigned int)ntohs(tcp_header->dest);

 

   }

   ip_hl_to_str(ntohl(src_ip), src_ip_str);

   ip_hl_to_str(ntohl(dest_ip), dest_ip_str);

 

   printk(KERN_INFO "IN packet info: src ip: %u = %s, src port: %u; dest ip: %u = %s, dest port: %u; proto: %u\n", src_ip, src_ip_str, src_port, dest_ip, dest_ip_str, dest_port, ip_header->protocol); 

 

   list_for_each(p, &regula.list) {

 

       i++;

 

       a_rule = list_entry(p, struct regula_firewall, list);

//printk(KERN_INFO "rule %d: a_rule->in_out = %u; a_rule->src_ip = %u; a_rule->src_netmask=%u; a_rule->src_port=%u; a_rule->dest_ip=%u; a_rule->dest_netmask=%u; a_rule->dest_port=%u; a_rule->proto=%u; a_rule->action=%u\n", i, a_rule->in_out, a_rule->src_ip, a_rule->src_netmask, a_rule->src_port, a_rule->dest_ip, a_rule->dest_netmask, a_rule->dest_port, a_rule->proto, a_rule->action);


 

       if (a_rule->in_out != 1) {

 

           printk(KERN_INFO "regula %d (a_rule->in_out:%u) nu se potriveste \n", i, a_rule->in_out);

 

           continue;

 

       } else {

 

           if ((a_rule->proto==1) && (ip_header->protocol != 6)) {

 

               printk(KERN_INFO "regula nu  se potriveste\n", i);

 

               continue;

 

           } else if ((a_rule->proto==2) && (ip_header->protocol != 17)) {

 

               printk(KERN_INFO "regula nu  se potriveste\n", i);

 

               continue;

 

           }

 

           if (a_rule->src_ip==0) {

 

              //

 

           } else {

 

              if (!check_ip(src_ip, a_rule->src_ip, a_rule->src_netmask)) {

 

                   printk(KERN_INFO "regula nu  se potriveste\n", i);

 

                  continue;

 

              }

 

           }

 

           if (a_rule->dest_ip == 0) {

 

               //

 

           } else {

 

               if (!check_ip(dest_ip, a_rule->dest_ip, a_rule->dest_netmask)) {

 

                   printk(KERN_INFO "regula nu  se potriveste\n", i);               

 

                  continue;

 

               }

 

           }


 

           if (a_rule->src_port==0) {
			   //potrivire

 

           } else if (src_port!=a_rule->src_port) {
			    printk(KERN_INFO "regula nu  se potriveste\n", i);

 

               continue;

 

           }

 

           if (a_rule->dest_port == 0) {
			   //potrivire

 

           }

 

           else if (dest_port!=a_rule->dest_port) {
			    printk(KERN_INFO "regula nu  se potriveste\n", i);

 

               continue;

 

           }

 

           //a fost gasita o potrivire, actioneaza in consecinta.

 

           if (a_rule->action==0) {

 

               printk(KERN_INFO "o potrivire %d, arunca pachetul\n", i);

 

               printk(KERN_INFO "---------------------------------------\n");

 

               return NF_DROP;

 

           } else {

 

               printk(KERN_INFO "a fost gasita o potrivire %d, accepta pachetul\n", i);

 

               printk(KERN_INFO "---------------------------------------\n");

 

               return NF_ACCEPT;

 

           }

 

       }

 

   }

 

   printk(KERN_INFO "nicio potrivire accepta pachetul\n");

 

   printk(KERN_INFO "---------------------------------------\n");

 

   return NF_ACCEPT;                

 

}
